package com.smartian.app.adapter;

import android.os.Parcelable;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.util.LongSparseArray;
import android.support.v4.view.PagerAdapter;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

/**
 * 【1】实现Fragment动态位置调整，数量增减
 * 【2】实现相同的Fragment复用
 *
 */
public abstract class AbstractFragmentPagerAdapter extends PagerAdapter {
    private static final String TAG = "FragmentPagerAdapter";
    private static final boolean DEBUG = false;

    private final FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction = null;
    private AbstractBaseFragment mCurrentPrimaryItem = null;
    private final LongSparseArray<String> fragmentViewTypeManager = new LongSparseArray<String>();
    public AbstractFragmentPagerAdapter(FragmentManager fm) {
        mFragmentManager = fm;
    }

    @Override
    public void startUpdate(ViewGroup container) {
        if (container.getId() == View.NO_ID) {  //viewPager必须赋值ID，否则无法添加fragment
            throw new IllegalStateException("ViewPager with adapter " + this
                    + " requires a view id");
        }
    }

    @SuppressWarnings("ReferenceEquality")
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        mCurTransaction = beginTransaction();
        final long itemId = getItemId(position);

        final int count = this.getFragmentTypeCount();
        int fragmentType = 0;
        if (count > 0) {
            fragmentType = getItemFragmentType(position);
        }
        if (fragmentType > 0 && fragmentType >= count) {
            throw new IllegalArgumentException("{fragmentType's number >= fragmentTypeCount's number} is illegal");
        }

        // 生成tag，用于保存和标记每个位置的fragment
        final String tagName = makeFragmentName(container.getId(), itemId); //生成tag
        final String oldFragmentName = fragmentViewTypeManager.get(fragmentType);
        AbstractBaseFragment fragment = (AbstractBaseFragment) mFragmentManager.findFragmentByTag(tagName);
        if (fragment != null) {
            final String fragmentClassName = fragment.getClass().getName();
            if (!fragmentClassName.equals(oldFragmentName)) {
                //如果发现新旧类型不一致，移除旧类型
                if (DEBUG) Log.v(TAG, "Removeing item #" + itemId + ": f=" + fragment);
                mCurTransaction.remove(fragment);
                //获取新类型
                fragment = getItem(null, position,tagName);
                if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
                mCurTransaction.add(container.getId(), fragment, tagName);
            } else {
                AbstractBaseFragment newFragment = getItem(fragment, position,tagName);
                //获取newFragment ，如果2次fragment不一致(类似Listview View复用逻辑)，移除旧的fragment
                if (newFragment != fragment) {
                    if (DEBUG) Log.v(TAG, "Removeing item #" + itemId + ": f=" + fragment);
                    mCurTransaction.remove(fragment);
                    fragment = newFragment;
                    if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
                    mCurTransaction.add(container.getId(), fragment, tagName);
                } else {
                    //如果获取到fragment与原来的是同一个，attach即可
                    if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
                    fragment.refreshFragment();
                    mCurTransaction.attach(fragment);
                }
            }
        } else {
            fragment = getItem(fragment, position,tagName);
            if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
            mCurTransaction.add(container.getId(), fragment, tagName);
        }

        if (fragment != null) {
            //保存类型，用来校验缓存的正确性
            String newFragmentName = fragment.getClass().getName();
            fragmentViewTypeManager.put(fragmentType,newFragmentName);
        }

        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {

        mCurTransaction = beginTransaction();
        if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
                + " v=" + ((AbstractBaseFragment) object).getView());
        mCurTransaction.detach((AbstractBaseFragment) object);  //dattach fragment
    }

    @SuppressWarnings("ReferenceEquality")
    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        AbstractBaseFragment fragment = (AbstractBaseFragment) object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem.setMenuVisibility(false);
                mCurrentPrimaryItem.setUserVisibleHint(false);
            }
            if (fragment != null) {
                fragment.setMenuVisibility(true);
                fragment.setUserVisibleHint(true);
            }
            mCurrentPrimaryItem = fragment;  //设置当前的fragment
        }
    }

    @Override
    public void finishUpdate(ViewGroup container) {
        if (mCurTransaction != null) {
            mCurTransaction.commitNowAllowingStateLoss();
            //提交，注意该方法将任务加入到mainLooper中，可能产生延迟
            mCurTransaction = null;
        }
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return ((AbstractBaseFragment) object).getView() == view;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
    }

    /**
     * 获取每个fragment的id，注意保证唯一性
     */
    public long getItemId(int position) {
        return position;
    }

    //生成tag
    public static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }

    public FragmentTransaction beginTransaction() {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        return mCurTransaction;
    }

    public FragmentManager getFragmentManager() {
        return mFragmentManager;
    }

    /**
     * 获取当前位置的fragment
     */
    public abstract AbstractBaseFragment getItem(AbstractBaseFragment contentFragment, int position,String tagName);
    /**
     * 获取当前位置的type  FragmentType
     */
    public abstract int getItemFragmentType(int position);
    /**
     * 获取当前类型的数量 FragmentCount
     */
    public abstract int getFragmentTypeCount();

    /**
     * 在ViewPager中调用，告诉ViewPager该位置的Fragment是可以被替换和更新的
     * 这里人可以继续优化，由于ViewPager.LayoutParams中的position是非public的，因此要优化可以在该类的基类中完成
     */
    @Override
    public int getItemPosition(Object object) {
        return PagerAdapter.POSITION_NONE;
    }
    public boolean isEmpty() {
        return getCount() == 0;
    }
}